module be.amd64asm_tests;

import std.stdio;

import utils : Arena, currTime, scaledNumberFmt;
import be.amd64asm;

struct CodegenTester
{
	Arena!ubyte arena;

	CodeGen_x86_64 gen;
	alias gen this;

	uint totalTests;
	uint numFailedTests;

	void assertHexAndReset(string file = __MODULE__, size_t line = __LINE__)(string expected) {
		import std.string : format;
		assertEqual!(file, line)(expected, format("%(%02X%)", gen.encoder.code));
		arena.clear();
	}

	private void assertEqual(string file = __MODULE__, size_t line = __LINE__, A, B)(A expected, B generated)
	{
		++totalTests;
		if (expected != generated)
		{
			writefln("%s expected", expected);
			writefln("%s generated", generated);
			stdout.flush();
			writefln("at %s:%s", file, line);

			++numFailedTests;
		}
	}
}

int testAmd64Asm()
{
	CodegenTester tester;
	tester.arena.setBuffer(new ubyte[65536], 65536);
	tester.gen.encoder.setBuffer(&tester.arena);

	auto startTime = currTime;

	// Add reg8, reg8
	foreach (Register regA; Register.min..RegisterMax) tester.addb(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.addb(Register.min, regB);
	tester.assertHexAndReset("00C000C100C200C34000C44000C54000C64000C74100C04100C14100C24100C34100C44100C54100C64100C700C000C800D000D84000E04000E84000F04000F84400C04400C84400D04400D84400E04400E84400F04400F8");

	// Add reg16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.addw(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.addw(Register.min, regB);
	tester.assertHexAndReset("6601C06601C16601C26601C36601C46601C56601C66601C7664101C0664101C1664101C2664101C3664101C4664101C5664101C6664101C76601C06601C86601D06601D86601E06601E86601F06601F8664401C0664401C8664401D0664401D8664401E0664401E8664401F0664401F8");

	// Add reg32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.addd(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.addd(Register.min, regB);
	tester.assertHexAndReset("01C001C101C201C301C401C501C601C74101C04101C14101C24101C34101C44101C54101C64101C701C001C801D001D801E001E801F001F84401C04401C84401D04401D84401E04401E84401F04401F8");

	// Add reg64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.addq(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.addq(Register.min, regB);
	tester.assertHexAndReset("4801C04801C14801C24801C34801C44801C54801C64801C74901C04901C14901C24901C34901C44901C54901C64901C74801C04801C84801D04801D84801E04801E84801F04801F84C01C04C01C84C01D04C01D84C01E04C01E84C01F04C01F8");

	// Add reg8, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.addb(regA, Imm8(0x24));
	tester.assertHexAndReset("80C02480C12480C22480C3244080C4244080C5244080C6244080C7244180C0244180C1244180C2244180C3244180C4244180C5244180C6244180C724");

	// Add reg16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.addw(regA, Imm8(0x24));
	tester.assertHexAndReset("6683C0246683C1246683C2246683C3246683C4246683C5246683C6246683C724664183C024664183C124664183C224664183C324664183C424664183C524664183C624664183C724");

	// Add reg32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.addd(regA, Imm8(0x24));
	tester.assertHexAndReset("83C02483C12483C22483C32483C42483C52483C62483C7244183C0244183C1244183C2244183C3244183C4244183C5244183C6244183C724");

	// Add reg64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.addq(regA, Imm8(0x24));
	tester.assertHexAndReset("4883C0244883C1244883C2244883C3244883C4244883C5244883C6244883C7244983C0244983C1244983C2244983C3244983C4244983C5244983C6244983C724");

	// Add reg16, imm16
	foreach (Register regA; Register.min..RegisterMax) tester.addw(regA, Imm16(0x2436));
	tester.assertHexAndReset("6681C036246681C136246681C236246681C336246681C436246681C536246681C636246681C73624664181C03624664181C13624664181C23624664181C33624664181C43624664181C53624664181C63624664181C73624");

	// Add reg32, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.addd(regA, Imm32(0x24364758));
	tester.assertHexAndReset("81C05847362481C15847362481C25847362481C35847362481C45847362481C55847362481C65847362481C7584736244181C0584736244181C1584736244181C2584736244181C3584736244181C4584736244181C5584736244181C6584736244181C758473624");

	// Add reg64, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.addq(regA, Imm32(0x24364758));
	tester.assertHexAndReset("4881C0584736244881C1584736244881C2584736244881C3584736244881C4584736244881C5584736244881C6584736244881C7584736244981C0584736244981C1584736244981C2584736244981C3584736244981C4584736244981C5584736244981C6584736244981C758473624");


	// Mov reg8, reg8
	foreach (Register regA; Register.min..RegisterMax) tester.movb(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.movb(Register.min, regB);
	tester.assertHexAndReset("88C088C188C288C34088C44088C54088C64088C74188C04188C14188C24188C34188C44188C54188C64188C788C088C888D088D84088E04088E84088F04088F84488C04488C84488D04488D84488E04488E84488F04488F8");

	// Mov reg16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.movw(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.movw(Register.min, regB);
	tester.assertHexAndReset("6689C06689C16689C26689C36689C46689C56689C66689C7664189C0664189C1664189C2664189C3664189C4664189C5664189C6664189C76689C06689C86689D06689D86689E06689E86689F06689F8664489C0664489C8664489D0664489D8664489E0664489E8664489F0664489F8");

	// Mov reg32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.movd(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.movd(Register.min, regB);
	tester.assertHexAndReset("89C089C189C289C389C489C589C689C74189C04189C14189C24189C34189C44189C54189C64189C789C089C889D089D889E089E889F089F84489C04489C84489D04489D84489E04489E84489F04489F8");

	// Mov reg64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.movq(Register.min, regB);
	tester.assertHexAndReset("4889C04889C14889C24889C34889C44889C54889C64889C74989C04989C14989C24989C34989C44989C54989C64989C74889C04889C84889D04889D84889E04889E84889F04889F84C89C04C89C84C89D04C89D84C89E04C89E84C89F04C89F8");

	// Mov reg8, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.movb(regA, Imm8(0x24));
	tester.assertHexAndReset("B024B124B224B32440B42440B52440B62440B72441B02441B12441B22441B32441B42441B52441B62441B724");

	// Mov reg16, imm16
	foreach (Register regA; Register.min..RegisterMax) tester.movw(regA, Imm16(0x2436));
	tester.assertHexAndReset("66B8362466B9362466BA362466BB362466BC362466BD362466BE362466BF36246641B836246641B936246641BA36246641BB36246641BC36246641BD36246641BE36246641BF3624");

	// Mov reg32, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.movd(regA, Imm32(0x24364758));
	tester.assertHexAndReset("B858473624B958473624BA58473624BB58473624BC58473624BD58473624BE58473624BF5847362441B85847362441B95847362441BA5847362441BB5847362441BC5847362441BD5847362441BE5847362441BF58473624");

	// Mov reg64, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, Imm32(0x24364758));
	tester.assertHexAndReset("48C7C05847362448C7C15847362448C7C25847362448C7C35847362448C7C45847362448C7C55847362448C7C65847362448C7C75847362449C7C05847362449C7C15847362449C7C25847362449C7C35847362449C7C45847362449C7C55847362449C7C65847362449C7C758473624");

	// Mov reg64, imm64
	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, Imm64(0x24364758AABBCCDD));
	tester.assertHexAndReset("48B8DDCCBBAA5847362448B9DDCCBBAA5847362448BADDCCBBAA5847362448BBDDCCBBAA5847362448BCDDCCBBAA5847362448BDDDCCBBAA5847362448BEDDCCBBAA5847362448BFDDCCBBAA5847362449B8DDCCBBAA5847362449B9DDCCBBAA5847362449BADDCCBBAA5847362449BBDDCCBBAA5847362449BCDDCCBBAA5847362449BDDDCCBBAA5847362449BEDDCCBBAA5847362449BFDDCCBBAA58473624");

	// Mov reg8 mem8
	foreach (Register regA; Register.min..RegisterMax) tester.movb(regA, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("8A0425887766558A0C25887766558A1425887766558A1C2588776655408A242588776655408A2C2588776655408A342588776655408A3C2588776655448A042588776655448A0C2588776655448A142588776655448A1C2588776655448A242588776655448A2C2588776655448A342588776655448A3C2588776655");

	// Mov reg16, mem16
	foreach (Register regA; Register.min..RegisterMax) tester.movw(regA, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("668B042588776655668B0C2588776655668B142588776655668B1C2588776655668B242588776655668B2C2588776655668B342588776655668B3C258877665566448B04258877665566448B0C258877665566448B14258877665566448B1C258877665566448B24258877665566448B2C258877665566448B34258877665566448B3C2588776655");

	// Mov reg32, mem32
	foreach (Register regA; Register.min..RegisterMax) tester.movd(regA, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("8B0425887766558B0C25887766558B1425887766558B1C25887766558B2425887766558B2C25887766558B3425887766558B3C2588776655448B042588776655448B0C2588776655448B142588776655448B1C2588776655448B242588776655448B2C2588776655448B342588776655448B3C2588776655");

	// Mov reg64, mem64
	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("488B042588776655488B0C2588776655488B142588776655488B1C2588776655488B242588776655488B2C2588776655488B342588776655488B3C25887766554C8B0425887766554C8B0C25887766554C8B1425887766554C8B1C25887766554C8B2425887766554C8B2C25887766554C8B3425887766554C8B3C2588776655");

	// Mov mem8, reg8
	foreach (Register regA; Register.min..RegisterMax) tester.movb(memAddrDisp32(0x55667788), regA);
	tester.assertHexAndReset("88042588776655880C258877665588142588776655881C2588776655408824258877665540882C2588776655408834258877665540883C2588776655448804258877665544880C2588776655448814258877665544881C2588776655448824258877665544882C2588776655448834258877665544883C2588776655");

	// Mov mem16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.movw(memAddrDisp32(0x55667788), regA);
	tester.assertHexAndReset("668904258877665566890C2588776655668914258877665566891C2588776655668924258877665566892C2588776655668934258877665566893C25887766556644890425887766556644890C25887766556644891425887766556644891C25887766556644892425887766556644892C25887766556644893425887766556644893C2588776655");

	// Mov mem32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.movd(memAddrDisp32(0x55667788), regA);
	tester.assertHexAndReset("89042588776655890C258877665589142588776655891C258877665589242588776655892C258877665589342588776655893C2588776655448904258877665544890C2588776655448914258877665544891C2588776655448924258877665544892C2588776655448934258877665544893C2588776655");

	// Mov mem64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.movq(memAddrDisp32(0x55667788), regA);
	tester.assertHexAndReset("488904258877665548890C2588776655488914258877665548891C2588776655488924258877665548892C2588776655488934258877665548893C25887766554C890425887766554C890C25887766554C891425887766554C891C25887766554C892425887766554C892C25887766554C893425887766554C893C2588776655");

	// Mov mem8, imm8
	tester.movb(memAddrDisp32(0x55667788), Imm8(0xAA));
	tester.assertHexAndReset("C6042588776655AA");

	// Mov mem16, imm16
	tester.movw(memAddrDisp32(0x55667788), Imm16(0xAABB));
	tester.assertHexAndReset("66C7042588776655BBAA");

	// Mov mem32, imm32
	tester.movd(memAddrDisp32(0x55667788), Imm32(0xAABBCCDD));
	tester.assertHexAndReset("C7042588776655DDCCBBAA");

	// Mov mem64 imm32
	// mov QWORD PTR [rsp-8], 0xffffffffaabbccdd
	tester.movq(memAddrBaseDisp8(Register.SP, cast(ubyte)(-8)), Imm32(0xAABBCCDD)); // -8
	tester.assertHexAndReset("48C74424F8DDCCBBAA");


	// test memory encoding
	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("488B042544332211488B0C2544332211488B142544332211488B1C2544332211488B242544332211488B2C2544332211488B342544332211488B3C25443322114C8B0425443322114C8B0C25443322114C8B1425443322114C8B1C25443322114C8B2425443322114C8B2C25443322114C8B3425443322114C8B3C2544332211");

	foreach (Register regA; Register.min..RegisterMax) if (regA != Register.SP) tester.movq(regA, memAddrIndexDisp32(regA, SibScale(0), 0x11223344));
	tester.assertHexAndReset("488B040544332211488B0C0D44332211488B141544332211488B1C1D44332211488B2C2D44332211488B343544332211488B3C3D443322114E8B0405443322114E8B0C0D443322114E8B1415443322114E8B1C1D443322114E8B2425443322114E8B2C2D443322114E8B3435443322114E8B3C3D44332211");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBase(regA));
	tester.assertHexAndReset("488B00488B09488B12488B1B488B2424488B6D00488B36488B3F4D8B004D8B094D8B124D8B1B4D8B24244D8B6D004D8B364D8B3F");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBaseDisp32(regA, 0x11223344));
	tester.assertHexAndReset("488B8044332211488B8944332211488B9244332211488B9B44332211488BA42444332211488BAD44332211488BB644332211488BBF443322114D8B80443322114D8B89443322114D8B92443322114D8B9B443322114D8BA424443322114D8BAD443322114D8BB6443322114D8BBF44332211");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBaseIndex(regA, regA == Register.SP ? Register.AX : regA, SibScale(1)));
	tester.assertHexAndReset("488B0440488B0C49488B1452488B1C5B488B2444488B6C6D00488B3476488B3C7F4F8B04404F8B0C494F8B14524F8B1C5B4F8B24644F8B6C6D004F8B34764F8B3C7F");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBaseIndexDisp32(regA, regA == Register.SP ? Register.AX : regA, SibScale(2), 0x11223344));
	tester.assertHexAndReset("488B848044332211488B8C8944332211488B949244332211488B9C9B44332211488BA48444332211488BACAD44332211488BB4B644332211488BBCBF443322114F8B8480443322114F8B8C89443322114F8B9492443322114F8B9C9B443322114F8BA4A4443322114F8BACAD443322114F8BB4B6443322114F8BBCBF44332211");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBaseDisp8(regA, -2));
	tester.assertHexAndReset("488B40FE488B49FE488B52FE488B5BFE488B6424FE488B6DFE488B76FE488B7FFE4D8B40FE4D8B49FE4D8B52FE4D8B5BFE4D8B6424FE4D8B6DFE4D8B76FE4D8B7FFE");

	foreach (Register regA; Register.min..RegisterMax) tester.movq(regA, memAddrBaseIndexDisp8(regA, regA == Register.SP ? Register.AX : regA, SibScale(3), -2));
	tester.assertHexAndReset("488B44C0FE488B4CC9FE488B54D2FE488B5CDBFE488B64C4FE488B6CEDFE488B74F6FE488B7CFFFE4F8B44C0FE4F8B4CC9FE4F8B54D2FE4F8B5CDBFE4F8B64E4FE4F8B6CEDFE4F8B74F6FE4F8B7CFFFE");


	// Cmp reg8, reg8
	foreach (Register regA; Register.min..RegisterMax) tester.cmpb(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.cmpb(Register.min, regB);
	tester.assertHexAndReset("38C038C138C238C34038C44038C54038C64038C74138C04138C14138C24138C34138C44138C54138C64138C738C038C838D038D84038E04038E84038F04038F84438C04438C84438D04438D84438E04438E84438F04438F8");

	// Cmp reg16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.cmpw(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.cmpw(Register.min, regB);
	tester.assertHexAndReset("6639C06639C16639C26639C36639C46639C56639C66639C7664139C0664139C1664139C2664139C3664139C4664139C5664139C6664139C76639C06639C86639D06639D86639E06639E86639F06639F8664439C0664439C8664439D0664439D8664439E0664439E8664439F0664439F8");

	// Cmp reg32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.cmpd(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.cmpd(Register.min, regB);
	tester.assertHexAndReset("39C039C139C239C339C439C539C639C74139C04139C14139C24139C34139C44139C54139C64139C739C039C839D039D839E039E839F039F84439C04439C84439D04439D84439E04439E84439F04439F8");

	// Cmp reg64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.cmpq(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.cmpq(Register.min, regB);
	tester.assertHexAndReset("4839C04839C14839C24839C34839C44839C54839C64839C74939C04939C14939C24939C34939C44939C54939C64939C74839C04839C84839D04839D84839E04839E84839F04839F84C39C04C39C84C39D04C39D84C39E04C39E84C39F04C39F8");

	// Cmp reg8, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.cmpb(regA, Imm8(0x24));
	tester.assertHexAndReset("80F82480F92480FA2480FB244080FC244080FD244080FE244080FF244180F8244180F9244180FA244180FB244180FC244180FD244180FE244180FF24");

	// Cmp reg16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.cmpw(regA, Imm8(0x24));
	tester.assertHexAndReset("6683F8246683F9246683FA246683FB246683FC246683FD246683FE246683FF24664183F824664183F924664183FA24664183FB24664183FC24664183FD24664183FE24664183FF24");

	// Cmp reg32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.cmpd(regA, Imm8(0x24));
	tester.assertHexAndReset("83F82483F92483FA2483FB2483FC2483FD2483FE2483FF244183F8244183F9244183FA244183FB244183FC244183FD244183FE244183FF24");

	// Cmp reg64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.cmpq(regA, Imm8(0x24));
	tester.assertHexAndReset("4883F8244883F9244883FA244883FB244883FC244883FD244883FE244883FF244983F8244983F9244983FA244983FB244983FC244983FD244983FE244983FF24");

	// Cmp reg16, imm16
	foreach (Register regA; Register.min..RegisterMax) tester.cmpw(regA, Imm16(0x2436));
	tester.assertHexAndReset("6681F836246681F936246681FA36246681FB36246681FC36246681FD36246681FE36246681FF3624664181F83624664181F93624664181FA3624664181FB3624664181FC3624664181FD3624664181FE3624664181FF3624");

	// Cmp reg32, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.cmpd(regA, Imm32(0x24364758));
	tester.assertHexAndReset("81F85847362481F95847362481FA5847362481FB5847362481FC5847362481FD5847362481FE5847362481FF584736244181F8584736244181F9584736244181FA584736244181FB584736244181FC584736244181FD584736244181FE584736244181FF58473624");

	// Cmp reg64, imm64
	foreach (Register regA; Register.min..RegisterMax) tester.cmpq(regA, Imm32(0x24364758));
	tester.assertHexAndReset("4881F8584736244881F9584736244881FA584736244881FB584736244881FC584736244881FD584736244881FE584736244881FF584736244981F8584736244981F9584736244981FA584736244981FB584736244981FC584736244981FD584736244981FE584736244981FF58473624");


	// not BYTE PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.notb(memAddrBase(reg));
	tester.assertHexAndReset("F610F611F612F613F61424F65500F616F61741F61041F61141F61241F61341F6142441F6550041F61641F617");

	// not WORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.notw(memAddrBase(reg));
	tester.assertHexAndReset("66F71066F71166F71266F71366F7142466F7550066F71666F7176641F7106641F7116641F7126641F7136641F714246641F755006641F7166641F717");

	// not DWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.notd(memAddrBase(reg));
	tester.assertHexAndReset("F710F711F712F713F71424F75500F716F71741F71041F71141F71241F71341F7142441F7550041F71641F717");

	// not QWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.notq(memAddrBase(reg));
	tester.assertHexAndReset("48F71048F71148F71248F71348F7142448F7550048F71648F71749F71049F71149F71249F71349F7142449F7550049F71649F717");

	// not reg8
	foreach (Register reg; Register.min..RegisterMax) tester.notb(reg);
	tester.assertHexAndReset("F6D0F6D1F6D2F6D340F6D440F6D540F6D640F6D741F6D041F6D141F6D241F6D341F6D441F6D541F6D641F6D7");

	// not reg16
	foreach (Register reg; Register.min..RegisterMax) tester.notw(reg);
	tester.assertHexAndReset("66F7D066F7D166F7D266F7D366F7D466F7D566F7D666F7D76641F7D06641F7D16641F7D26641F7D36641F7D46641F7D56641F7D66641F7D7");

	// not reg32
	foreach (Register reg; Register.min..RegisterMax) tester.notd(reg);
	tester.assertHexAndReset("F7D0F7D1F7D2F7D3F7D4F7D5F7D6F7D741F7D041F7D141F7D241F7D341F7D441F7D541F7D641F7D7");

	// not reg64
	foreach (Register reg; Register.min..RegisterMax) tester.notq(reg);
	tester.assertHexAndReset("48F7D048F7D148F7D248F7D348F7D448F7D548F7D648F7D749F7D049F7D149F7D249F7D349F7D449F7D549F7D649F7D7");


	// jmp
	tester.jmp(Imm8(0xAA));
	tester.jmp(Imm32(0xAABBCCDD));
	tester.assertHexAndReset("EBAAE9DDCCBBAA");

	// je
	tester.jcc(Condition.E, Imm8(0xAA));
	tester.jcc(Condition.E, Imm32(0xAABBCCDD));
	tester.assertHexAndReset("74AA0F84DDCCBBAA");

	//jne
	tester.jcc(Condition.NE, Imm8(0xAA));
	tester.jcc(Condition.NE, Imm32(0xAABBCCDD));
	tester.assertHexAndReset("75AA0F85DDCCBBAA");


	// sete
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.E, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.E, memAddrBase(reg));
	tester.assertHexAndReset("0F94C00F94C10F94C20F94C3400F94C4400F94C5400F94C6400F94C7410F94C0410F94C1410F94C2410F94C3410F94C4410F94C5410F94C6410F94C70F94000F94010F94020F94030F9404240F9445000F94060F9407410F9400410F9401410F9402410F9403410F940424410F944500410F9406410F9407");

	// setne
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.NE, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.NE, memAddrBase(reg));
	tester.assertHexAndReset("0F95C00F95C10F95C20F95C3400F95C4400F95C5400F95C6400F95C7410F95C0410F95C1410F95C2410F95C3410F95C4410F95C5410F95C6410F95C70F95000F95010F95020F95030F9504240F9545000F95060F9507410F9500410F9501410F9502410F9503410F950424410F954500410F9506410F9507");

	// setg
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.G, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.setcc(Condition.G, memAddrBase(reg));
	tester.assertHexAndReset("0F9FC00F9FC10F9FC20F9FC3400F9FC4400F9FC5400F9FC6400F9FC7410F9FC0410F9FC1410F9FC2410F9FC3410F9FC4410F9FC5410F9FC6410F9FC70F9F000F9F010F9F020F9F030F9F04240F9F45000F9F060F9F07410F9F00410F9F01410F9F02410F9F03410F9F0424410F9F4500410F9F06410F9F07");



	// testb
	foreach (Register reg; Register.min..RegisterMax) tester.testb(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.testb(Register.min, reg);
	tester.assertHexAndReset("84C084C184C284C34084C44084C54084C64084C74184C04184C14184C24184C34184C44184C54184C64184C784C084C884D084D84084E04084E84084F04084F84484C04484C84484D04484D84484E04484E84484F04484F8");

	// testw
	foreach (Register reg; Register.min..RegisterMax) tester.testw(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.testw(Register.min, reg);
	tester.assertHexAndReset("6685C06685C16685C26685C36685C46685C56685C66685C7664185C0664185C1664185C2664185C3664185C4664185C5664185C6664185C76685C06685C86685D06685D86685E06685E86685F06685F8664485C0664485C8664485D0664485D8664485E0664485E8664485F0664485F8");

	// testd
	foreach (Register reg; Register.min..RegisterMax) tester.testd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.testd(Register.min, reg);
	tester.assertHexAndReset("85C085C185C285C385C485C585C685C74185C04185C14185C24185C34185C44185C54185C64185C785C085C885D085D885E085E885F085F84485C04485C84485D04485D84485E04485E84485F04485F8");

	// testq
	foreach (Register reg; Register.min..RegisterMax) tester.testq(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.testq(Register.min, reg);
	tester.assertHexAndReset("4885C04885C14885C24885C34885C44885C54885C64885C74985C04985C14985C24985C34985C44985C54985C64985C74885C04885C84885D04885D84885E04885E84885F04885F84C85C04C85C84C85D04C85D84C85E04C85E84C85F04C85F8");


	// Imul reg16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB);
	tester.assertHexAndReset("660FAFC0660FAFC8660FAFD0660FAFD8660FAFE0660FAFE8660FAFF0660FAFF866440FAFC066440FAFC866440FAFD066440FAFD866440FAFE066440FAFE866440FAFF066440FAFF8660FAFC0660FAFC1660FAFC2660FAFC3660FAFC4660FAFC5660FAFC6660FAFC766410FAFC066410FAFC166410FAFC266410FAFC366410FAFC466410FAFC566410FAFC666410FAFC7");

	// Imul reg32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB);
	tester.assertHexAndReset("0FAFC00FAFC80FAFD00FAFD80FAFE00FAFE80FAFF00FAFF8440FAFC0440FAFC8440FAFD0440FAFD8440FAFE0440FAFE8440FAFF0440FAFF80FAFC00FAFC10FAFC20FAFC30FAFC40FAFC50FAFC60FAFC7410FAFC0410FAFC1410FAFC2410FAFC3410FAFC4410FAFC5410FAFC6410FAFC7");

	// Imul reg64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB);
	tester.assertHexAndReset("480FAFC0480FAFC8480FAFD0480FAFD8480FAFE0480FAFE8480FAFF0480FAFF84C0FAFC04C0FAFC84C0FAFD04C0FAFD84C0FAFE04C0FAFE84C0FAFF04C0FAFF8480FAFC0480FAFC1480FAFC2480FAFC3480FAFC4480FAFC5480FAFC6480FAFC7490FAFC0490FAFC1490FAFC2490FAFC3490FAFC4490FAFC5490FAFC6490FAFC7");

	// Imul reg16, mem16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("660FAF00660FAF01660FAF02660FAF03660FAF0424660FAF4500660FAF06660FAF0766410FAF0066410FAF0166410FAF0266410FAF0366410FAF042466410FAF450066410FAF0666410FAF07");

	// Imul reg32, mem32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("0FAF000FAF010FAF020FAF030FAF04240FAF45000FAF060FAF07410FAF00410FAF01410FAF02410FAF03410FAF0424410FAF4500410FAF06410FAF07");

	// Imul reg64, mem64
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("480FAF00480FAF01480FAF02480FAF03480FAF0424480FAF4500480FAF06480FAF07490FAF00490FAF01490FAF02490FAF03490FAF0424490FAF4500490FAF06490FAF07");


	// Imul reg16, reg16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("666BC024666BC824666BD024666BD824666BE024666BE824666BF024666BF82466446BC02466446BC82466446BD02466446BD82466446BE02466446BE82466446BF02466446BF824666BC024666BC124666BC224666BC324666BC424666BC524666BC624666BC72466416BC02466416BC12466416BC22466416BC32466416BC42466416BC52466416BC62466416BC724");

	// Imul reg32, reg32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("6BC0246BC8246BD0246BD8246BE0246BE8246BF0246BF824446BC024446BC824446BD024446BD824446BE024446BE824446BF024446BF8246BC0246BC1246BC2246BC3246BC4246BC5246BC6246BC724416BC024416BC124416BC224416BC324416BC424416BC524416BC624416BC724");

	// Imul reg64, reg64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("486BC024486BC824486BD024486BD824486BE024486BE824486BF024486BF8244C6BC0244C6BC8244C6BD0244C6BD8244C6BE0244C6BE8244C6BF0244C6BF824486BC024486BC124486BC224486BC324486BC424486BC524486BC624486BC724496BC024496BC124496BC224496BC324496BC424496BC524496BC624496BC724");

	// Imul reg16, reg16, imm16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min, Imm16(0x2436));
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB, Imm16(0x2436));
	tester.assertHexAndReset("6669C036246669C836246669D036246669D836246669E036246669E836246669F036246669F83624664469C03624664469C83624664469D03624664469D83624664469E03624664469E83624664469F03624664469F836246669C036246669C136246669C236246669C336246669C436246669C536246669C636246669C73624664169C03624664169C13624664169C23624664169C33624664169C43624664169C53624664169C63624664169C73624");

	// Imul reg32, reg32, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min, Imm32(0x24364758));
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB, Imm32(0x24364758));
	tester.assertHexAndReset("69C05847362469C85847362469D05847362469D85847362469E05847362469E85847362469F05847362469F8584736244469C0584736244469C8584736244469D0584736244469D8584736244469E0584736244469E8584736244469F0584736244469F85847362469C05847362469C15847362469C25847362469C35847362469C45847362469C55847362469C65847362469C7584736244169C0584736244169C1584736244169C2584736244169C3584736244169C4584736244169C5584736244169C6584736244169C758473624");

	// Imul reg64, reg64, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min, Imm32(0x24364758));
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB, Imm32(0x24364758));
	tester.assertHexAndReset("4869C0584736244869C8584736244869D0584736244869D8584736244869E0584736244869E8584736244869F0584736244869F8584736244C69C0584736244C69C8584736244C69D0584736244C69D8584736244C69E0584736244C69E8584736244C69F0584736244C69F8584736244869C0584736244869C1584736244869C2584736244869C3584736244869C4584736244869C5584736244869C6584736244869C7584736244969C0584736244969C1584736244969C2584736244969C3584736244969C4584736244969C5584736244969C6584736244969C758473624");


	// Imul reg16, mem16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("666B0024666B0124666B0224666B0324666B042424666B450024666B0624666B072466416B002466416B012466416B022466416B032466416B04242466416B45002466416B062466416B0724");

	// Imul reg32, mem32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("6B00246B01246B02246B03246B0424246B4500246B06246B0724416B0024416B0124416B0224416B0324416B042424416B450024416B0624416B0724");

	// Imul reg64, mem64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("486B0024486B0124486B0224486B0324486B042424486B450024486B0624486B0724496B0024496B0124496B0224496B0324496B042424496B450024496B0624496B0724");



	// cwd / cdq / cqo
	tester.cwd();
	tester.cdq();
	tester.cqo();
	tester.assertHexAndReset("6699994899");

	// pop reg16
	foreach (Register reg; Register.min..RegisterMax) tester.popw(reg);
	tester.assertHexAndReset("66586659665A665B665C665D665E665F66415866415966415A66415B66415C66415D66415E66415F");

	// pop reg64
	foreach (Register reg; Register.min..RegisterMax) tester.popq(reg);
	tester.assertHexAndReset("58595A5B5C5D5E5F41584159415A415B415C415D415E415F");

	// pop WORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.popw(memAddrBase(reg));
	tester.assertHexAndReset("668F00668F01668F02668F03668F0424668F4500668F06668F0766418F0066418F0166418F0266418F0366418F042466418F450066418F0666418F07");

	// pop QWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.popq(memAddrBase(reg));
	tester.assertHexAndReset("8F008F018F028F038F04248F45008F068F07418F00418F01418F02418F03418F0424418F4500418F06418F07");


	// push reg16
	foreach (Register reg; Register.min..RegisterMax) tester.pushw(reg);
	tester.assertHexAndReset("66506651665266536654665566566657664150664151664152664153664154664155664156664157");

	// push reg64
	foreach (Register reg; Register.min..RegisterMax) tester.pushq(reg);
	tester.assertHexAndReset("505152535455565741504151415241534154415541564157");

	// push WORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.pushw(memAddrBase(reg));
	tester.assertHexAndReset("66FF3066FF3166FF3266FF3366FF342466FF750066FF3666FF376641FF306641FF316641FF326641FF336641FF34246641FF75006641FF366641FF37");

	// push QWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.pushq(memAddrBase(reg));
	tester.assertHexAndReset("FF30FF31FF32FF33FF3424FF7500FF36FF3741FF3041FF3141FF3241FF3341FF342441FF750041FF3641FF37");

	// push Imm8/16/32
	tester.pushb(Imm8(0x11));
	tester.pushw(Imm16(0x1122));
	tester.pushd(Imm32(0x11223344));
	tester.assertHexAndReset("6A11666822116844332211");


	// mul reg8
	foreach (Register reg; Register.min..RegisterMax) tester.mulb(reg);
	tester.assertHexAndReset("F6E0F6E1F6E2F6E340F6E440F6E540F6E640F6E741F6E041F6E141F6E241F6E341F6E441F6E541F6E641F6E7");

	// mul reg16
	foreach (Register reg; Register.min..RegisterMax) tester.mulw(reg);
	tester.assertHexAndReset("66F7E066F7E166F7E266F7E366F7E466F7E566F7E666F7E76641F7E06641F7E16641F7E26641F7E36641F7E46641F7E56641F7E66641F7E7");

	// mul reg32
	foreach (Register reg; Register.min..RegisterMax) tester.muld(reg);
	tester.assertHexAndReset("F7E0F7E1F7E2F7E3F7E4F7E5F7E6F7E741F7E041F7E141F7E241F7E341F7E441F7E541F7E641F7E7");

	// mul reg64
	foreach (Register reg; Register.min..RegisterMax) tester.mulq(reg);
	tester.assertHexAndReset("48F7E048F7E148F7E248F7E348F7E448F7E548F7E648F7E749F7E049F7E149F7E249F7E349F7E449F7E549F7E649F7E7");

	// mul BYTE PTR "reg"
	foreach (Register reg; Register.min..RegisterMax) tester.mulb(memAddrBase(reg));
	tester.assertHexAndReset("F620F621F622F623F62424F66500F626F62741F62041F62141F62241F62341F6242441F6650041F62641F627");

	// mul WORD PTR "reg"
	foreach (Register reg; Register.min..RegisterMax) tester.mulw(memAddrBase(reg));
	tester.assertHexAndReset("66F72066F72166F72266F72366F7242466F7650066F72666F7276641F7206641F7216641F7226641F7236641F724246641F765006641F7266641F727");

	// mul DWORD PTR "reg"
	foreach (Register reg; Register.min..RegisterMax) tester.muld(memAddrBase(reg));
	tester.assertHexAndReset("F720F721F722F723F72424F76500F726F72741F72041F72141F72241F72341F7242441F7650041F72641F727");

	// mul QWORD PTR "reg"
	foreach (Register reg; Register.min..RegisterMax) tester.mulq(memAddrBase(reg));
	tester.assertHexAndReset("48F72048F72148F72248F72348F7242448F7650048F72648F72749F72049F72149F72249F72349F7242449F7650049F72649F727");


	// inc BYTE PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.incb(memAddrBase(reg));
	tester.assertHexAndReset("FE00FE01FE02FE03FE0424FE4500FE06FE0741FE0041FE0141FE0241FE0341FE042441FE450041FE0641FE07");

	// inc WORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.incw(memAddrBase(reg));
	tester.assertHexAndReset("66FF0066FF0166FF0266FF0366FF042466FF450066FF0666FF076641FF006641FF016641FF026641FF036641FF04246641FF45006641FF066641FF07");

	// inc DWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.incd(memAddrBase(reg));
	tester.assertHexAndReset("FF00FF01FF02FF03FF0424FF4500FF06FF0741FF0041FF0141FF0241FF0341FF042441FF450041FF0641FF07");

	// inc QWORD PTR [reg]
	foreach (Register reg; Register.min..RegisterMax) tester.incq(memAddrBase(reg));
	tester.assertHexAndReset("48FF0048FF0148FF0248FF0348FF042448FF450048FF0648FF0749FF0049FF0149FF0249FF0349FF042449FF450049FF0649FF07");

	// inc reg8
	foreach (Register reg; Register.min..RegisterMax) tester.incb(reg);
	tester.assertHexAndReset("FEC0FEC1FEC2FEC340FEC440FEC540FEC640FEC741FEC041FEC141FEC241FEC341FEC441FEC541FEC641FEC7");

	// inc reg16
	foreach (Register reg; Register.min..RegisterMax) tester.incw(reg);
	tester.assertHexAndReset("66FFC066FFC166FFC266FFC366FFC466FFC566FFC666FFC76641FFC06641FFC16641FFC26641FFC36641FFC46641FFC56641FFC66641FFC7");

	// inc reg32
	foreach (Register reg; Register.min..RegisterMax) tester.incd(reg);
	tester.assertHexAndReset("FFC0FFC1FFC2FFC3FFC4FFC5FFC6FFC741FFC041FFC141FFC241FFC341FFC441FFC541FFC641FFC7");

	// inc reg64
	foreach (Register reg; Register.min..RegisterMax) tester.incq(reg);
	tester.assertHexAndReset("48FFC048FFC148FFC248FFC348FFC448FFC548FFC648FFC749FFC049FFC149FFC249FFC349FFC449FFC549FFC649FFC7");

	// test memory encoding
	tester.incq(memAddrDisp32(0x11223344));
	tester.assertHexAndReset("48FF042544332211");

	foreach (Register regA; Register.min..RegisterMax) if (regA != Register.SP) tester.incq(memAddrIndexDisp32(regA, SibScale(0), 0x11223344));
	tester.assertHexAndReset("48FF04054433221148FF040D4433221148FF04154433221148FF041D4433221148FF042D4433221148FF04354433221148FF043D443322114AFF0405443322114AFF040D443322114AFF0415443322114AFF041D443322114AFF0425443322114AFF042D443322114AFF0435443322114AFF043D44332211");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBase(regA));
	tester.assertHexAndReset("48FF0048FF0148FF0248FF0348FF042448FF450048FF0648FF0749FF0049FF0149FF0249FF0349FF042449FF450049FF0649FF07");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBaseDisp32(regA, 0x11223344));
	tester.assertHexAndReset("48FF804433221148FF814433221148FF824433221148FF834433221148FF84244433221148FF854433221148FF864433221148FF874433221149FF804433221149FF814433221149FF824433221149FF834433221149FF84244433221149FF854433221149FF864433221149FF8744332211");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBaseIndex(regA, regA == Register.SP ? Register.AX : regA, SibScale(1)));
	tester.assertHexAndReset("48FF044048FF044948FF045248FF045B48FF044448FF446D0048FF047648FF047F4BFF04404BFF04494BFF04524BFF045B4BFF04644BFF446D004BFF04764BFF047F");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBaseIndexDisp32(regA, regA == Register.SP ? Register.AX : regA, SibScale(2), 0x11223344));
	tester.assertHexAndReset("48FF84804433221148FF84894433221148FF84924433221148FF849B4433221148FF84844433221148FF84AD4433221148FF84B64433221148FF84BF443322114BFF8480443322114BFF8489443322114BFF8492443322114BFF849B443322114BFF84A4443322114BFF84AD443322114BFF84B6443322114BFF84BF44332211");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBaseDisp8(regA, -2));
	tester.assertHexAndReset("48FF40FE48FF41FE48FF42FE48FF43FE48FF4424FE48FF45FE48FF46FE48FF47FE49FF40FE49FF41FE49FF42FE49FF43FE49FF4424FE49FF45FE49FF46FE49FF47FE");

	foreach (Register regA; Register.min..RegisterMax) tester.incq(memAddrBaseIndexDisp8(regA, regA == Register.SP ? Register.AX : regA, SibScale(3), -2));
	tester.assertHexAndReset("48FF44C0FE48FF44C9FE48FF44D2FE48FF44DBFE48FF44C4FE48FF44EDFE48FF44F6FE48FF44FFFE4BFF44C0FE4BFF44C9FE4BFF44D2FE4BFF44DBFE4BFF44E4FE4BFF44EDFE4BFF44F6FE4BFF44FFFE");


	// cvtss2sd
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sd(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F30F5AC0F30F5AC8F30F5AD0F30F5AD8F30F5AE0F30F5AE8F30F5AF0F30F5AF8F3440F5AC0F3440F5AC8F3440F5AD0F3440F5AD8F3440F5AE0F3440F5AE8F3440F5AF0F3440F5AF8F30F5AC0F30F5AC1F30F5AC2F30F5AC3F30F5AC4F30F5AC5F30F5AC6F30F5AC7F3410F5AC0F3410F5AC1F3410F5AC2F3410F5AC3F3410F5AC4F3410F5AC5F3410F5AC6F3410F5AC7F30F5A042588776655F30F5A0C2588776655F30F5A142588776655F30F5A1C2588776655F30F5A242588776655F30F5A2C2588776655F30F5A342588776655F30F5A3C2588776655F3440F5A042588776655F3440F5A0C2588776655F3440F5A142588776655F3440F5A1C2588776655F3440F5A242588776655F3440F5A2C2588776655F3440F5A342588776655F3440F5A3C2588776655");

	// cvtsd2ss
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2ss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2ss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2ss(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F20F5AC0F20F5AC8F20F5AD0F20F5AD8F20F5AE0F20F5AE8F20F5AF0F20F5AF8F2440F5AC0F2440F5AC8F2440F5AD0F2440F5AD8F2440F5AE0F2440F5AE8F2440F5AF0F2440F5AF8F20F5AC0F20F5AC1F20F5AC2F20F5AC3F20F5AC4F20F5AC5F20F5AC6F20F5AC7F2410F5AC0F2410F5AC1F2410F5AC2F2410F5AC3F2410F5AC4F2410F5AC5F2410F5AC6F2410F5AC7F20F5A042588776655F20F5A0C2588776655F20F5A142588776655F20F5A1C2588776655F20F5A242588776655F20F5A2C2588776655F20F5A342588776655F20F5A3C2588776655F2440F5A042588776655F2440F5A0C2588776655F2440F5A142588776655F2440F5A1C2588776655F2440F5A242588776655F2440F5A2C2588776655F2440F5A342588776655F2440F5A3C2588776655");

	// cvtss2sid
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sid(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sid(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2sid(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F30F2DC0F30F2DC8F30F2DD0F30F2DD8F30F2DE0F30F2DE8F30F2DF0F30F2DF8F3440F2DC0F3440F2DC8F3440F2DD0F3440F2DD8F3440F2DE0F3440F2DE8F3440F2DF0F3440F2DF8F30F2DC0F30F2DC1F30F2DC2F30F2DC3F30F2DC4F30F2DC5F30F2DC6F30F2DC7F3410F2DC0F3410F2DC1F3410F2DC2F3410F2DC3F3410F2DC4F3410F2DC5F3410F2DC6F3410F2DC7F30F2D042588776655F30F2D0C2588776655F30F2D142588776655F30F2D1C2588776655F30F2D242588776655F30F2D2C2588776655F30F2D342588776655F30F2D3C2588776655F3440F2D042588776655F3440F2D0C2588776655F3440F2D142588776655F3440F2D1C2588776655F3440F2D242588776655F3440F2D2C2588776655F3440F2D342588776655F3440F2D3C2588776655");

	// cvtss2siq
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2siq(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2siq(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtss2siq(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F3480F2DC0F3480F2DC8F3480F2DD0F3480F2DD8F3480F2DE0F3480F2DE8F3480F2DF0F3480F2DF8F34C0F2DC0F34C0F2DC8F34C0F2DD0F34C0F2DD8F34C0F2DE0F34C0F2DE8F34C0F2DF0F34C0F2DF8F3480F2DC0F3480F2DC1F3480F2DC2F3480F2DC3F3480F2DC4F3480F2DC5F3480F2DC6F3480F2DC7F3490F2DC0F3490F2DC1F3490F2DC2F3490F2DC3F3490F2DC4F3490F2DC5F3490F2DC6F3490F2DC7F3480F2D042588776655F3480F2D0C2588776655F3480F2D142588776655F3480F2D1C2588776655F3480F2D242588776655F3480F2D2C2588776655F3480F2D342588776655F3480F2D3C2588776655F34C0F2D042588776655F34C0F2D0C2588776655F34C0F2D142588776655F34C0F2D1C2588776655F34C0F2D242588776655F34C0F2D2C2588776655F34C0F2D342588776655F34C0F2D3C2588776655");

	// cvtsid2ss
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2ss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2ss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2ss(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F30F2AC0F30F2AC8F30F2AD0F30F2AD8F30F2AE0F30F2AE8F30F2AF0F30F2AF8F3440F2AC0F3440F2AC8F3440F2AD0F3440F2AD8F3440F2AE0F3440F2AE8F3440F2AF0F3440F2AF8F30F2AC0F30F2AC1F30F2AC2F30F2AC3F30F2AC4F30F2AC5F30F2AC6F30F2AC7F3410F2AC0F3410F2AC1F3410F2AC2F3410F2AC3F3410F2AC4F3410F2AC5F3410F2AC6F3410F2AC7F30F2A042588776655F30F2A0C2588776655F30F2A142588776655F30F2A1C2588776655F30F2A242588776655F30F2A2C2588776655F30F2A342588776655F30F2A3C2588776655F3440F2A042588776655F3440F2A0C2588776655F3440F2A142588776655F3440F2A1C2588776655F3440F2A242588776655F3440F2A2C2588776655F3440F2A342588776655F3440F2A3C2588776655");

	// cvtsiq2ss
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2ss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2ss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2ss(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F3480F2AC0F3480F2AC8F3480F2AD0F3480F2AD8F3480F2AE0F3480F2AE8F3480F2AF0F3480F2AF8F34C0F2AC0F34C0F2AC8F34C0F2AD0F34C0F2AD8F34C0F2AE0F34C0F2AE8F34C0F2AF0F34C0F2AF8F3480F2AC0F3480F2AC1F3480F2AC2F3480F2AC3F3480F2AC4F3480F2AC5F3480F2AC6F3480F2AC7F3490F2AC0F3490F2AC1F3490F2AC2F3490F2AC3F3490F2AC4F3490F2AC5F3490F2AC6F3490F2AC7F3480F2A042588776655F3480F2A0C2588776655F3480F2A142588776655F3480F2A1C2588776655F3480F2A242588776655F3480F2A2C2588776655F3480F2A342588776655F3480F2A3C2588776655F34C0F2A042588776655F34C0F2A0C2588776655F34C0F2A142588776655F34C0F2A1C2588776655F34C0F2A242588776655F34C0F2A2C2588776655F34C0F2A342588776655F34C0F2A3C2588776655");

	// cvttss2sid
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2sid(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2sid(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2sid(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F30F2CC0F30F2CC8F30F2CD0F30F2CD8F30F2CE0F30F2CE8F30F2CF0F30F2CF8F3440F2CC0F3440F2CC8F3440F2CD0F3440F2CD8F3440F2CE0F3440F2CE8F3440F2CF0F3440F2CF8F30F2CC0F30F2CC1F30F2CC2F30F2CC3F30F2CC4F30F2CC5F30F2CC6F30F2CC7F3410F2CC0F3410F2CC1F3410F2CC2F3410F2CC3F3410F2CC4F3410F2CC5F3410F2CC6F3410F2CC7F30F2C042588776655F30F2C0C2588776655F30F2C142588776655F30F2C1C2588776655F30F2C242588776655F30F2C2C2588776655F30F2C342588776655F30F2C3C2588776655F3440F2C042588776655F3440F2C0C2588776655F3440F2C142588776655F3440F2C1C2588776655F3440F2C242588776655F3440F2C2C2588776655F3440F2C342588776655F3440F2C3C2588776655");

	// cvttss2siq
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2siq(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2siq(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttss2siq(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F3480F2CC0F3480F2CC8F3480F2CD0F3480F2CD8F3480F2CE0F3480F2CE8F3480F2CF0F3480F2CF8F34C0F2CC0F34C0F2CC8F34C0F2CD0F34C0F2CD8F34C0F2CE0F34C0F2CE8F34C0F2CF0F34C0F2CF8F3480F2CC0F3480F2CC1F3480F2CC2F3480F2CC3F3480F2CC4F3480F2CC5F3480F2CC6F3480F2CC7F3490F2CC0F3490F2CC1F3490F2CC2F3490F2CC3F3490F2CC4F3490F2CC5F3490F2CC6F3490F2CC7F3480F2C042588776655F3480F2C0C2588776655F3480F2C142588776655F3480F2C1C2588776655F3480F2C242588776655F3480F2C2C2588776655F3480F2C342588776655F3480F2C3C2588776655F34C0F2C042588776655F34C0F2C0C2588776655F34C0F2C142588776655F34C0F2C1C2588776655F34C0F2C242588776655F34C0F2C2C2588776655F34C0F2C342588776655F34C0F2C3C2588776655");

	// cvtsd2sid
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2sid(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2sid(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2sid(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F20F2DC0F20F2DC8F20F2DD0F20F2DD8F20F2DE0F20F2DE8F20F2DF0F20F2DF8F2440F2DC0F2440F2DC8F2440F2DD0F2440F2DD8F2440F2DE0F2440F2DE8F2440F2DF0F2440F2DF8F20F2DC0F20F2DC1F20F2DC2F20F2DC3F20F2DC4F20F2DC5F20F2DC6F20F2DC7F2410F2DC0F2410F2DC1F2410F2DC2F2410F2DC3F2410F2DC4F2410F2DC5F2410F2DC6F2410F2DC7F20F2D042588776655F20F2D0C2588776655F20F2D142588776655F20F2D1C2588776655F20F2D242588776655F20F2D2C2588776655F20F2D342588776655F20F2D3C2588776655F2440F2D042588776655F2440F2D0C2588776655F2440F2D142588776655F2440F2D1C2588776655F2440F2D242588776655F2440F2D2C2588776655F2440F2D342588776655F2440F2D3C2588776655");

	// cvtsd2siq
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2siq(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2siq(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsd2siq(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F2480F2DC0F2480F2DC8F2480F2DD0F2480F2DD8F2480F2DE0F2480F2DE8F2480F2DF0F2480F2DF8F24C0F2DC0F24C0F2DC8F24C0F2DD0F24C0F2DD8F24C0F2DE0F24C0F2DE8F24C0F2DF0F24C0F2DF8F2480F2DC0F2480F2DC1F2480F2DC2F2480F2DC3F2480F2DC4F2480F2DC5F2480F2DC6F2480F2DC7F2490F2DC0F2490F2DC1F2490F2DC2F2490F2DC3F2490F2DC4F2490F2DC5F2490F2DC6F2490F2DC7F2480F2D042588776655F2480F2D0C2588776655F2480F2D142588776655F2480F2D1C2588776655F2480F2D242588776655F2480F2D2C2588776655F2480F2D342588776655F2480F2D3C2588776655F24C0F2D042588776655F24C0F2D0C2588776655F24C0F2D142588776655F24C0F2D1C2588776655F24C0F2D242588776655F24C0F2D2C2588776655F24C0F2D342588776655F24C0F2D3C2588776655");

	// cvtsid2sd
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2sd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2sd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsid2sd(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F20F2AC0F20F2AC8F20F2AD0F20F2AD8F20F2AE0F20F2AE8F20F2AF0F20F2AF8F2440F2AC0F2440F2AC8F2440F2AD0F2440F2AD8F2440F2AE0F2440F2AE8F2440F2AF0F2440F2AF8F20F2AC0F20F2AC1F20F2AC2F20F2AC3F20F2AC4F20F2AC5F20F2AC6F20F2AC7F2410F2AC0F2410F2AC1F2410F2AC2F2410F2AC3F2410F2AC4F2410F2AC5F2410F2AC6F2410F2AC7F20F2A042588776655F20F2A0C2588776655F20F2A142588776655F20F2A1C2588776655F20F2A242588776655F20F2A2C2588776655F20F2A342588776655F20F2A3C2588776655F2440F2A042588776655F2440F2A0C2588776655F2440F2A142588776655F2440F2A1C2588776655F2440F2A242588776655F2440F2A2C2588776655F2440F2A342588776655F2440F2A3C2588776655");

	// cvtsiq2sd
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2sd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2sd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvtsiq2sd(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F2480F2AC0F2480F2AC8F2480F2AD0F2480F2AD8F2480F2AE0F2480F2AE8F2480F2AF0F2480F2AF8F24C0F2AC0F24C0F2AC8F24C0F2AD0F24C0F2AD8F24C0F2AE0F24C0F2AE8F24C0F2AF0F24C0F2AF8F2480F2AC0F2480F2AC1F2480F2AC2F2480F2AC3F2480F2AC4F2480F2AC5F2480F2AC6F2480F2AC7F2490F2AC0F2490F2AC1F2490F2AC2F2490F2AC3F2490F2AC4F2490F2AC5F2490F2AC6F2490F2AC7F2480F2A042588776655F2480F2A0C2588776655F2480F2A142588776655F2480F2A1C2588776655F2480F2A242588776655F2480F2A2C2588776655F2480F2A342588776655F2480F2A3C2588776655F24C0F2A042588776655F24C0F2A0C2588776655F24C0F2A142588776655F24C0F2A1C2588776655F24C0F2A242588776655F24C0F2A2C2588776655F24C0F2A342588776655F24C0F2A3C2588776655");

	// cvttsd2sid
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2sid(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2sid(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2sid(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F20F2CC0F20F2CC8F20F2CD0F20F2CD8F20F2CE0F20F2CE8F20F2CF0F20F2CF8F2440F2CC0F2440F2CC8F2440F2CD0F2440F2CD8F2440F2CE0F2440F2CE8F2440F2CF0F2440F2CF8F20F2CC0F20F2CC1F20F2CC2F20F2CC3F20F2CC4F20F2CC5F20F2CC6F20F2CC7F2410F2CC0F2410F2CC1F2410F2CC2F2410F2CC3F2410F2CC4F2410F2CC5F2410F2CC6F2410F2CC7F20F2C042588776655F20F2C0C2588776655F20F2C142588776655F20F2C1C2588776655F20F2C242588776655F20F2C2C2588776655F20F2C342588776655F20F2C3C2588776655F2440F2C042588776655F2440F2C0C2588776655F2440F2C142588776655F2440F2C1C2588776655F2440F2C242588776655F2440F2C2C2588776655F2440F2C342588776655F2440F2C3C2588776655");

	// cvttsd2siq
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2siq(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2siq(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.cvttsd2siq(reg, memAddrDisp32(0x55667788));
	tester.assertHexAndReset("F2480F2CC0F2480F2CC8F2480F2CD0F2480F2CD8F2480F2CE0F2480F2CE8F2480F2CF0F2480F2CF8F24C0F2CC0F24C0F2CC8F24C0F2CD0F24C0F2CD8F24C0F2CE0F24C0F2CE8F24C0F2CF0F24C0F2CF8F2480F2CC0F2480F2CC1F2480F2CC2F2480F2CC3F2480F2CC4F2480F2CC5F2480F2CC6F2480F2CC7F2490F2CC0F2490F2CC1F2490F2CC2F2490F2CC3F2490F2CC4F2490F2CC5F2490F2CC6F2490F2CC7F2480F2C042588776655F2480F2C0C2588776655F2480F2C142588776655F2480F2C1C2588776655F2480F2C242588776655F2480F2C2C2588776655F2480F2C342588776655F2480F2C3C2588776655F24C0F2C042588776655F24C0F2C0C2588776655F24C0F2C142588776655F24C0F2C1C2588776655F24C0F2C242588776655F24C0F2C2C2588776655F24C0F2C342588776655F24C0F2C3C2588776655");



	// movss
	foreach (Register reg; Register.min..RegisterMax) tester.movss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movss(reg, memAddrDisp32(0x11223344));
	foreach (Register reg; Register.min..RegisterMax) tester.movss(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("F30F10C0F30F10C8F30F10D0F30F10D8F30F10E0F30F10E8F30F10F0F30F10F8F3440F10C0F3440F10C8F3440F10D0F3440F10D8F3440F10E0F3440F10E8F3440F10F0F3440F10F8F30F10C0F30F10C1F30F10C2F30F10C3F30F10C4F30F10C5F30F10C6F30F10C7F3410F10C0F3410F10C1F3410F10C2F3410F10C3F3410F10C4F3410F10C5F3410F10C6F3410F10C7F30F10042544332211F30F100C2544332211F30F10142544332211F30F101C2544332211F30F10242544332211F30F102C2544332211F30F10342544332211F30F103C2544332211F3440F10042544332211F3440F100C2544332211F3440F10142544332211F3440F101C2544332211F3440F10242544332211F3440F102C2544332211F3440F10342544332211F3440F103C2544332211F30F11042544332211F30F110C2544332211F30F11142544332211F30F111C2544332211F30F11242544332211F30F112C2544332211F30F11342544332211F30F113C2544332211F3440F11042544332211F3440F110C2544332211F3440F11142544332211F3440F111C2544332211F3440F11242544332211F3440F112C2544332211F3440F11342544332211F3440F113C2544332211");

	// movsd
	foreach (Register reg; Register.min..RegisterMax) tester.movsd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movsd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movsd(reg, memAddrDisp32(0x11223344));
	foreach (Register reg; Register.min..RegisterMax) tester.movsd(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("F20F10C0F20F10C8F20F10D0F20F10D8F20F10E0F20F10E8F20F10F0F20F10F8F2440F10C0F2440F10C8F2440F10D0F2440F10D8F2440F10E0F2440F10E8F2440F10F0F2440F10F8F20F10C0F20F10C1F20F10C2F20F10C3F20F10C4F20F10C5F20F10C6F20F10C7F2410F10C0F2410F10C1F2410F10C2F2410F10C3F2410F10C4F2410F10C5F2410F10C6F2410F10C7F20F10042544332211F20F100C2544332211F20F10142544332211F20F101C2544332211F20F10242544332211F20F102C2544332211F20F10342544332211F20F103C2544332211F2440F10042544332211F2440F100C2544332211F2440F10142544332211F2440F101C2544332211F2440F10242544332211F2440F102C2544332211F2440F10342544332211F2440F103C2544332211F20F11042544332211F20F110C2544332211F20F11142544332211F20F111C2544332211F20F11242544332211F20F112C2544332211F20F11342544332211F20F113C2544332211F2440F11042544332211F2440F110C2544332211F2440F11142544332211F2440F111C2544332211F2440F11242544332211F2440F112C2544332211F2440F11342544332211F2440F113C2544332211");

	// movaps
	foreach (Register reg; Register.min..RegisterMax) tester.movaps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movaps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movaps(reg, memAddrDisp32(0x11223344));
	foreach (Register reg; Register.min..RegisterMax) tester.movaps(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("0F28C00F28C80F28D00F28D80F28E00F28E80F28F00F28F8440F28C0440F28C8440F28D0440F28D8440F28E0440F28E8440F28F0440F28F80F28C00F28C10F28C20F28C30F28C40F28C50F28C60F28C7410F28C0410F28C1410F28C2410F28C3410F28C4410F28C5410F28C6410F28C70F280425443322110F280C25443322110F281425443322110F281C25443322110F282425443322110F282C25443322110F283425443322110F283C2544332211440F28042544332211440F280C2544332211440F28142544332211440F281C2544332211440F28242544332211440F282C2544332211440F28342544332211440F283C25443322110F290425443322110F290C25443322110F291425443322110F291C25443322110F292425443322110F292C25443322110F293425443322110F293C2544332211440F29042544332211440F290C2544332211440F29142544332211440F291C2544332211440F29242544332211440F292C2544332211440F29342544332211440F293C2544332211");

	// movups
	foreach (Register reg; Register.min..RegisterMax) tester.movups(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movups(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movups(reg, memAddrDisp32(0x11223344));
	foreach (Register reg; Register.min..RegisterMax) tester.movups(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("0F10C00F10C80F10D00F10D80F10E00F10E80F10F00F10F8440F10C0440F10C8440F10D0440F10D8440F10E0440F10E8440F10F0440F10F80F10C00F10C10F10C20F10C30F10C40F10C50F10C60F10C7410F10C0410F10C1410F10C2410F10C3410F10C4410F10C5410F10C6410F10C70F100425443322110F100C25443322110F101425443322110F101C25443322110F102425443322110F102C25443322110F103425443322110F103C2544332211440F10042544332211440F100C2544332211440F10142544332211440F101C2544332211440F10242544332211440F102C2544332211440F10342544332211440F103C25443322110F110425443322110F110C25443322110F111425443322110F111C25443322110F112425443322110F112C25443322110F113425443322110F113C2544332211440F11042544332211440F110C2544332211440F11142544332211440F111C2544332211440F11242544332211440F112C2544332211440F11342544332211440F113C2544332211");

	// movd_xr
	foreach (Register reg; Register.min..RegisterMax) tester.movd_xr(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movd_xr(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movd_xr(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F6EC0660F6EC8660F6ED0660F6ED8660F6EE0660F6EE8660F6EF0660F6EF866440F6EC066440F6EC866440F6ED066440F6ED866440F6EE066440F6EE866440F6EF066440F6EF8660F6EC0660F6EC1660F6EC2660F6EC3660F6EC4660F6EC5660F6EC6660F6EC766410F6EC066410F6EC166410F6EC266410F6EC366410F6EC466410F6EC566410F6EC666410F6EC7660F6E042544332211660F6E0C2544332211660F6E142544332211660F6E1C2544332211660F6E242544332211660F6E2C2544332211660F6E342544332211660F6E3C254433221166440F6E04254433221166440F6E0C254433221166440F6E14254433221166440F6E1C254433221166440F6E24254433221166440F6E2C254433221166440F6E34254433221166440F6E3C2544332211");

	// movq_xr
	foreach (Register reg; Register.min..RegisterMax) tester.movq_xr(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movq_xr(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movq_xr(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("66480F6EC066480F6EC866480F6ED066480F6ED866480F6EE066480F6EE866480F6EF066480F6EF8664C0F6EC0664C0F6EC8664C0F6ED0664C0F6ED8664C0F6EE0664C0F6EE8664C0F6EF0664C0F6EF866480F6EC066480F6EC166480F6EC266480F6EC366480F6EC466480F6EC566480F6EC666480F6EC766490F6EC066490F6EC166490F6EC266490F6EC366490F6EC466490F6EC566490F6EC666490F6EC766480F6E04254433221166480F6E0C254433221166480F6E14254433221166480F6E1C254433221166480F6E24254433221166480F6E2C254433221166480F6E34254433221166480F6E3C2544332211664C0F6E042544332211664C0F6E0C2544332211664C0F6E142544332211664C0F6E1C2544332211664C0F6E242544332211664C0F6E2C2544332211664C0F6E342544332211664C0F6E3C2544332211");

	// movd_rx
	foreach (Register reg; Register.min..RegisterMax) tester.movd_rx(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movd_rx(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movd_rx(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("660F7EC0660F7EC1660F7EC2660F7EC3660F7EC4660F7EC5660F7EC6660F7EC766410F7EC066410F7EC166410F7EC266410F7EC366410F7EC466410F7EC566410F7EC666410F7EC7660F7EC0660F7EC8660F7ED0660F7ED8660F7EE0660F7EE8660F7EF0660F7EF866440F7EC066440F7EC866440F7ED066440F7ED866440F7EE066440F7EE866440F7EF066440F7EF8660F7E042544332211660F7E0C2544332211660F7E142544332211660F7E1C2544332211660F7E242544332211660F7E2C2544332211660F7E342544332211660F7E3C254433221166440F7E04254433221166440F7E0C254433221166440F7E14254433221166440F7E1C254433221166440F7E24254433221166440F7E2C254433221166440F7E34254433221166440F7E3C2544332211");

	// movq_rx
	foreach (Register reg; Register.min..RegisterMax) tester.movq_rx(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.movq_rx(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.movq_rx(memAddrDisp32(0x11223344), reg);
	tester.assertHexAndReset("66480F7EC066480F7EC166480F7EC266480F7EC366480F7EC466480F7EC566480F7EC666480F7EC766490F7EC066490F7EC166490F7EC266490F7EC366490F7EC466490F7EC566490F7EC666490F7EC766480F7EC066480F7EC866480F7ED066480F7ED866480F7EE066480F7EE866480F7EF066480F7EF8664C0F7EC0664C0F7EC8664C0F7ED0664C0F7ED8664C0F7EE0664C0F7EE8664C0F7EF0664C0F7EF866480F7E04254433221166480F7E0C254433221166480F7E14254433221166480F7E1C254433221166480F7E24254433221166480F7E2C254433221166480F7E34254433221166480F7E3C2544332211664C0F7E042544332211664C0F7E0C2544332211664C0F7E142544332211664C0F7E1C2544332211664C0F7E242544332211664C0F7E2C2544332211664C0F7E342544332211664C0F7E3C2544332211");

	// andps
	foreach (Register reg; Register.min..RegisterMax) tester.andps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.andps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.andps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F54C00F54C80F54D00F54D80F54E00F54E80F54F00F54F8440F54C0440F54C8440F54D0440F54D8440F54E0440F54E8440F54F0440F54F80F54C00F54C10F54C20F54C30F54C40F54C50F54C60F54C7410F54C0410F54C1410F54C2410F54C3410F54C4410F54C5410F54C6410F54C70F540425443322110F540C25443322110F541425443322110F541C25443322110F542425443322110F542C25443322110F543425443322110F543C2544332211440F54042544332211440F540C2544332211440F54142544332211440F541C2544332211440F54242544332211440F542C2544332211440F54342544332211440F543C2544332211");

	// andpd
	foreach (Register reg; Register.min..RegisterMax) tester.andpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.andpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.andpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F54C0660F54C8660F54D0660F54D8660F54E0660F54E8660F54F0660F54F866440F54C066440F54C866440F54D066440F54D866440F54E066440F54E866440F54F066440F54F8660F54C0660F54C1660F54C2660F54C3660F54C4660F54C5660F54C6660F54C766410F54C066410F54C166410F54C266410F54C366410F54C466410F54C566410F54C666410F54C7660F54042544332211660F540C2544332211660F54142544332211660F541C2544332211660F54242544332211660F542C2544332211660F54342544332211660F543C254433221166440F5404254433221166440F540C254433221166440F5414254433221166440F541C254433221166440F5424254433221166440F542C254433221166440F5434254433221166440F543C2544332211");

	// orps
	foreach (Register reg; Register.min..RegisterMax) tester.orps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.orps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.orps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F56C00F56C80F56D00F56D80F56E00F56E80F56F00F56F8440F56C0440F56C8440F56D0440F56D8440F56E0440F56E8440F56F0440F56F80F56C00F56C10F56C20F56C30F56C40F56C50F56C60F56C7410F56C0410F56C1410F56C2410F56C3410F56C4410F56C5410F56C6410F56C70F560425443322110F560C25443322110F561425443322110F561C25443322110F562425443322110F562C25443322110F563425443322110F563C2544332211440F56042544332211440F560C2544332211440F56142544332211440F561C2544332211440F56242544332211440F562C2544332211440F56342544332211440F563C2544332211");

	// orpd
	foreach (Register reg; Register.min..RegisterMax) tester.orpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.orpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.orpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F56C0660F56C8660F56D0660F56D8660F56E0660F56E8660F56F0660F56F866440F56C066440F56C866440F56D066440F56D866440F56E066440F56E866440F56F066440F56F8660F56C0660F56C1660F56C2660F56C3660F56C4660F56C5660F56C6660F56C766410F56C066410F56C166410F56C266410F56C366410F56C466410F56C566410F56C666410F56C7660F56042544332211660F560C2544332211660F56142544332211660F561C2544332211660F56242544332211660F562C2544332211660F56342544332211660F563C254433221166440F5604254433221166440F560C254433221166440F5614254433221166440F561C254433221166440F5624254433221166440F562C254433221166440F5634254433221166440F563C2544332211");

	// xorps
	foreach (Register reg; Register.min..RegisterMax) tester.xorps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.xorps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.xorps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F57C00F57C80F57D00F57D80F57E00F57E80F57F00F57F8440F57C0440F57C8440F57D0440F57D8440F57E0440F57E8440F57F0440F57F80F57C00F57C10F57C20F57C30F57C40F57C50F57C60F57C7410F57C0410F57C1410F57C2410F57C3410F57C4410F57C5410F57C6410F57C70F570425443322110F570C25443322110F571425443322110F571C25443322110F572425443322110F572C25443322110F573425443322110F573C2544332211440F57042544332211440F570C2544332211440F57142544332211440F571C2544332211440F57242544332211440F572C2544332211440F57342544332211440F573C2544332211");

	// xorpd
	foreach (Register reg; Register.min..RegisterMax) tester.xorpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.xorpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.xorpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F57C0660F57C8660F57D0660F57D8660F57E0660F57E8660F57F0660F57F866440F57C066440F57C866440F57D066440F57D866440F57E066440F57E866440F57F066440F57F8660F57C0660F57C1660F57C2660F57C3660F57C4660F57C5660F57C6660F57C766410F57C066410F57C166410F57C266410F57C366410F57C466410F57C566410F57C666410F57C7660F57042544332211660F570C2544332211660F57142544332211660F571C2544332211660F57242544332211660F572C2544332211660F57342544332211660F573C254433221166440F5704254433221166440F570C254433221166440F5714254433221166440F571C254433221166440F5724254433221166440F572C254433221166440F5734254433221166440F573C2544332211");

	// addps
	foreach (Register reg; Register.min..RegisterMax) tester.addps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.addps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.addps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F58C00F58C80F58D00F58D80F58E00F58E80F58F00F58F8440F58C0440F58C8440F58D0440F58D8440F58E0440F58E8440F58F0440F58F80F58C00F58C10F58C20F58C30F58C40F58C50F58C60F58C7410F58C0410F58C1410F58C2410F58C3410F58C4410F58C5410F58C6410F58C70F580425443322110F580C25443322110F581425443322110F581C25443322110F582425443322110F582C25443322110F583425443322110F583C2544332211440F58042544332211440F580C2544332211440F58142544332211440F581C2544332211440F58242544332211440F582C2544332211440F58342544332211440F583C2544332211");

	// addpd
	foreach (Register reg; Register.min..RegisterMax) tester.addpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.addpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.addpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F58C0660F58C8660F58D0660F58D8660F58E0660F58E8660F58F0660F58F866440F58C066440F58C866440F58D066440F58D866440F58E066440F58E866440F58F066440F58F8660F58C0660F58C1660F58C2660F58C3660F58C4660F58C5660F58C6660F58C766410F58C066410F58C166410F58C266410F58C366410F58C466410F58C566410F58C666410F58C7660F58042544332211660F580C2544332211660F58142544332211660F581C2544332211660F58242544332211660F582C2544332211660F58342544332211660F583C254433221166440F5804254433221166440F580C254433221166440F5814254433221166440F581C254433221166440F5824254433221166440F582C254433221166440F5834254433221166440F583C2544332211");

	// mulps
	foreach (Register reg; Register.min..RegisterMax) tester.mulps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.mulps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.mulps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F59C00F59C80F59D00F59D80F59E00F59E80F59F00F59F8440F59C0440F59C8440F59D0440F59D8440F59E0440F59E8440F59F0440F59F80F59C00F59C10F59C20F59C30F59C40F59C50F59C60F59C7410F59C0410F59C1410F59C2410F59C3410F59C4410F59C5410F59C6410F59C70F590425443322110F590C25443322110F591425443322110F591C25443322110F592425443322110F592C25443322110F593425443322110F593C2544332211440F59042544332211440F590C2544332211440F59142544332211440F591C2544332211440F59242544332211440F592C2544332211440F59342544332211440F593C2544332211");

	// mulpd
	foreach (Register reg; Register.min..RegisterMax) tester.mulpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.mulpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.mulpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F59C0660F59C8660F59D0660F59D8660F59E0660F59E8660F59F0660F59F866440F59C066440F59C866440F59D066440F59D866440F59E066440F59E866440F59F066440F59F8660F59C0660F59C1660F59C2660F59C3660F59C4660F59C5660F59C6660F59C766410F59C066410F59C166410F59C266410F59C366410F59C466410F59C566410F59C666410F59C7660F59042544332211660F590C2544332211660F59142544332211660F591C2544332211660F59242544332211660F592C2544332211660F59342544332211660F593C254433221166440F5904254433221166440F590C254433221166440F5914254433221166440F591C254433221166440F5924254433221166440F592C254433221166440F5934254433221166440F593C2544332211");

	// subps
	foreach (Register reg; Register.min..RegisterMax) tester.subps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.subps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.subps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F5CC00F5CC80F5CD00F5CD80F5CE00F5CE80F5CF00F5CF8440F5CC0440F5CC8440F5CD0440F5CD8440F5CE0440F5CE8440F5CF0440F5CF80F5CC00F5CC10F5CC20F5CC30F5CC40F5CC50F5CC60F5CC7410F5CC0410F5CC1410F5CC2410F5CC3410F5CC4410F5CC5410F5CC6410F5CC70F5C0425443322110F5C0C25443322110F5C1425443322110F5C1C25443322110F5C2425443322110F5C2C25443322110F5C3425443322110F5C3C2544332211440F5C042544332211440F5C0C2544332211440F5C142544332211440F5C1C2544332211440F5C242544332211440F5C2C2544332211440F5C342544332211440F5C3C2544332211");

	// subpd
	foreach (Register reg; Register.min..RegisterMax) tester.subpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.subpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.subpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F5CC0660F5CC8660F5CD0660F5CD8660F5CE0660F5CE8660F5CF0660F5CF866440F5CC066440F5CC866440F5CD066440F5CD866440F5CE066440F5CE866440F5CF066440F5CF8660F5CC0660F5CC1660F5CC2660F5CC3660F5CC4660F5CC5660F5CC6660F5CC766410F5CC066410F5CC166410F5CC266410F5CC366410F5CC466410F5CC566410F5CC666410F5CC7660F5C042544332211660F5C0C2544332211660F5C142544332211660F5C1C2544332211660F5C242544332211660F5C2C2544332211660F5C342544332211660F5C3C254433221166440F5C04254433221166440F5C0C254433221166440F5C14254433221166440F5C1C254433221166440F5C24254433221166440F5C2C254433221166440F5C34254433221166440F5C3C2544332211");

	// divps
	foreach (Register reg; Register.min..RegisterMax) tester.divps(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.divps(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.divps(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F5EC00F5EC80F5ED00F5ED80F5EE00F5EE80F5EF00F5EF8440F5EC0440F5EC8440F5ED0440F5ED8440F5EE0440F5EE8440F5EF0440F5EF80F5EC00F5EC10F5EC20F5EC30F5EC40F5EC50F5EC60F5EC7410F5EC0410F5EC1410F5EC2410F5EC3410F5EC4410F5EC5410F5EC6410F5EC70F5E0425443322110F5E0C25443322110F5E1425443322110F5E1C25443322110F5E2425443322110F5E2C25443322110F5E3425443322110F5E3C2544332211440F5E042544332211440F5E0C2544332211440F5E142544332211440F5E1C2544332211440F5E242544332211440F5E2C2544332211440F5E342544332211440F5E3C2544332211");

	// divpd
	foreach (Register reg; Register.min..RegisterMax) tester.divpd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.divpd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.divpd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F5EC0660F5EC8660F5ED0660F5ED8660F5EE0660F5EE8660F5EF0660F5EF866440F5EC066440F5EC866440F5ED066440F5ED866440F5EE066440F5EE866440F5EF066440F5EF8660F5EC0660F5EC1660F5EC2660F5EC3660F5EC4660F5EC5660F5EC6660F5EC766410F5EC066410F5EC166410F5EC266410F5EC366410F5EC466410F5EC566410F5EC666410F5EC7660F5E042544332211660F5E0C2544332211660F5E142544332211660F5E1C2544332211660F5E242544332211660F5E2C2544332211660F5E342544332211660F5E3C254433221166440F5E04254433221166440F5E0C254433221166440F5E14254433221166440F5E1C254433221166440F5E24254433221166440F5E2C254433221166440F5E34254433221166440F5E3C2544332211");

	// cmpss
	foreach (ubyte i; 0..8) tester.cmpss(cast(Register)i, cast(Register)(7-i), Imm8(i));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpss(reg, Register.min, Imm8(0));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpss(Register.min, reg, Imm8(0));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpss(reg, memAddrDisp32(0x11223344), Imm8(0));
	tester.assertHexAndReset("F30FC2C700F30FC2CE01F30FC2D502F30FC2DC03F30FC2E304F30FC2EA05F30FC2F106F30FC2F807F30FC2C000F30FC2C800F30FC2D000F30FC2D800F30FC2E000F30FC2E800F30FC2F000F30FC2F800F3440FC2C000F3440FC2C800F3440FC2D000F3440FC2D800F3440FC2E000F3440FC2E800F3440FC2F000F3440FC2F800F30FC2C000F30FC2C100F30FC2C200F30FC2C300F30FC2C400F30FC2C500F30FC2C600F30FC2C700F3410FC2C000F3410FC2C100F3410FC2C200F3410FC2C300F3410FC2C400F3410FC2C500F3410FC2C600F3410FC2C700F30FC204254433221100F30FC20C254433221100F30FC214254433221100F30FC21C254433221100F30FC224254433221100F30FC22C254433221100F30FC234254433221100F30FC23C254433221100F3440FC204254433221100F3440FC20C254433221100F3440FC214254433221100F3440FC21C254433221100F3440FC224254433221100F3440FC22C254433221100F3440FC234254433221100F3440FC23C254433221100");

	// cmpsd
	foreach (ubyte i; 0..8) tester.cmpsd(cast(Register)i, cast(Register)(7-i), Imm8(i));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpsd(reg, Register.min, Imm8(0));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpsd(Register.min, reg, Imm8(0));
	foreach (Register reg; Register.min..RegisterMax) tester.cmpsd(reg, memAddrDisp32(0x11223344), Imm8(0));
	tester.assertHexAndReset("F20FC2C700F20FC2CE01F20FC2D502F20FC2DC03F20FC2E304F20FC2EA05F20FC2F106F20FC2F807F20FC2C000F20FC2C800F20FC2D000F20FC2D800F20FC2E000F20FC2E800F20FC2F000F20FC2F800F2440FC2C000F2440FC2C800F2440FC2D000F2440FC2D800F2440FC2E000F2440FC2E800F2440FC2F000F2440FC2F800F20FC2C000F20FC2C100F20FC2C200F20FC2C300F20FC2C400F20FC2C500F20FC2C600F20FC2C700F2410FC2C000F2410FC2C100F2410FC2C200F2410FC2C300F2410FC2C400F2410FC2C500F2410FC2C600F2410FC2C700F20FC204254433221100F20FC20C254433221100F20FC214254433221100F20FC21C254433221100F20FC224254433221100F20FC22C254433221100F20FC234254433221100F20FC23C254433221100F2440FC204254433221100F2440FC20C254433221100F2440FC214254433221100F2440FC21C254433221100F2440FC224254433221100F2440FC22C254433221100F2440FC234254433221100F2440FC23C254433221100");

	// ucomiss
	foreach (Register reg; Register.min..RegisterMax) tester.ucomiss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.ucomiss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.ucomiss(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("0F2EC00F2EC80F2ED00F2ED80F2EE00F2EE80F2EF00F2EF8440F2EC0440F2EC8440F2ED0440F2ED8440F2EE0440F2EE8440F2EF0440F2EF80F2EC00F2EC10F2EC20F2EC30F2EC40F2EC50F2EC60F2EC7410F2EC0410F2EC1410F2EC2410F2EC3410F2EC4410F2EC5410F2EC6410F2EC70F2E0425443322110F2E0C25443322110F2E1425443322110F2E1C25443322110F2E2425443322110F2E2C25443322110F2E3425443322110F2E3C2544332211440F2E042544332211440F2E0C2544332211440F2E142544332211440F2E1C2544332211440F2E242544332211440F2E2C2544332211440F2E342544332211440F2E3C2544332211");

	// ucomisd
	foreach (Register reg; Register.min..RegisterMax) tester.ucomisd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.ucomisd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.ucomisd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("660F2EC0660F2EC8660F2ED0660F2ED8660F2EE0660F2EE8660F2EF0660F2EF866440F2EC066440F2EC866440F2ED066440F2ED866440F2EE066440F2EE866440F2EF066440F2EF8660F2EC0660F2EC1660F2EC2660F2EC3660F2EC4660F2EC5660F2EC6660F2EC766410F2EC066410F2EC166410F2EC266410F2EC366410F2EC466410F2EC566410F2EC666410F2EC7660F2E042544332211660F2E0C2544332211660F2E142544332211660F2E1C2544332211660F2E242544332211660F2E2C2544332211660F2E342544332211660F2E3C254433221166440F2E04254433221166440F2E0C254433221166440F2E14254433221166440F2E1C254433221166440F2E24254433221166440F2E2C254433221166440F2E34254433221166440F2E3C2544332211");

	// addss
	foreach (Register reg; Register.min..RegisterMax) tester.addss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.addss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.addss(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F30F58C0F30F58C8F30F58D0F30F58D8F30F58E0F30F58E8F30F58F0F30F58F8F3440F58C0F3440F58C8F3440F58D0F3440F58D8F3440F58E0F3440F58E8F3440F58F0F3440F58F8F30F58C0F30F58C1F30F58C2F30F58C3F30F58C4F30F58C5F30F58C6F30F58C7F3410F58C0F3410F58C1F3410F58C2F3410F58C3F3410F58C4F3410F58C5F3410F58C6F3410F58C7F30F58042544332211F30F580C2544332211F30F58142544332211F30F581C2544332211F30F58242544332211F30F582C2544332211F30F58342544332211F30F583C2544332211F3440F58042544332211F3440F580C2544332211F3440F58142544332211F3440F581C2544332211F3440F58242544332211F3440F582C2544332211F3440F58342544332211F3440F583C2544332211");

	// addsd
	foreach (Register reg; Register.min..RegisterMax) tester.addsd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.addsd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.addsd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F20F58C0F20F58C8F20F58D0F20F58D8F20F58E0F20F58E8F20F58F0F20F58F8F2440F58C0F2440F58C8F2440F58D0F2440F58D8F2440F58E0F2440F58E8F2440F58F0F2440F58F8F20F58C0F20F58C1F20F58C2F20F58C3F20F58C4F20F58C5F20F58C6F20F58C7F2410F58C0F2410F58C1F2410F58C2F2410F58C3F2410F58C4F2410F58C5F2410F58C6F2410F58C7F20F58042544332211F20F580C2544332211F20F58142544332211F20F581C2544332211F20F58242544332211F20F582C2544332211F20F58342544332211F20F583C2544332211F2440F58042544332211F2440F580C2544332211F2440F58142544332211F2440F581C2544332211F2440F58242544332211F2440F582C2544332211F2440F58342544332211F2440F583C2544332211");

	// subss
	foreach (Register reg; Register.min..RegisterMax) tester.subss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.subss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.subss(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F30F5CC0F30F5CC8F30F5CD0F30F5CD8F30F5CE0F30F5CE8F30F5CF0F30F5CF8F3440F5CC0F3440F5CC8F3440F5CD0F3440F5CD8F3440F5CE0F3440F5CE8F3440F5CF0F3440F5CF8F30F5CC0F30F5CC1F30F5CC2F30F5CC3F30F5CC4F30F5CC5F30F5CC6F30F5CC7F3410F5CC0F3410F5CC1F3410F5CC2F3410F5CC3F3410F5CC4F3410F5CC5F3410F5CC6F3410F5CC7F30F5C042544332211F30F5C0C2544332211F30F5C142544332211F30F5C1C2544332211F30F5C242544332211F30F5C2C2544332211F30F5C342544332211F30F5C3C2544332211F3440F5C042544332211F3440F5C0C2544332211F3440F5C142544332211F3440F5C1C2544332211F3440F5C242544332211F3440F5C2C2544332211F3440F5C342544332211F3440F5C3C2544332211");

	// subsd
	foreach (Register reg; Register.min..RegisterMax) tester.subsd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.subsd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.subsd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F20F5CC0F20F5CC8F20F5CD0F20F5CD8F20F5CE0F20F5CE8F20F5CF0F20F5CF8F2440F5CC0F2440F5CC8F2440F5CD0F2440F5CD8F2440F5CE0F2440F5CE8F2440F5CF0F2440F5CF8F20F5CC0F20F5CC1F20F5CC2F20F5CC3F20F5CC4F20F5CC5F20F5CC6F20F5CC7F2410F5CC0F2410F5CC1F2410F5CC2F2410F5CC3F2410F5CC4F2410F5CC5F2410F5CC6F2410F5CC7F20F5C042544332211F20F5C0C2544332211F20F5C142544332211F20F5C1C2544332211F20F5C242544332211F20F5C2C2544332211F20F5C342544332211F20F5C3C2544332211F2440F5C042544332211F2440F5C0C2544332211F2440F5C142544332211F2440F5C1C2544332211F2440F5C242544332211F2440F5C2C2544332211F2440F5C342544332211F2440F5C3C2544332211");

	// mulss
	foreach (Register reg; Register.min..RegisterMax) tester.mulss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.mulss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.mulss(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F30F59C0F30F59C8F30F59D0F30F59D8F30F59E0F30F59E8F30F59F0F30F59F8F3440F59C0F3440F59C8F3440F59D0F3440F59D8F3440F59E0F3440F59E8F3440F59F0F3440F59F8F30F59C0F30F59C1F30F59C2F30F59C3F30F59C4F30F59C5F30F59C6F30F59C7F3410F59C0F3410F59C1F3410F59C2F3410F59C3F3410F59C4F3410F59C5F3410F59C6F3410F59C7F30F59042544332211F30F590C2544332211F30F59142544332211F30F591C2544332211F30F59242544332211F30F592C2544332211F30F59342544332211F30F593C2544332211F3440F59042544332211F3440F590C2544332211F3440F59142544332211F3440F591C2544332211F3440F59242544332211F3440F592C2544332211F3440F59342544332211F3440F593C2544332211");

	// mulsd
	foreach (Register reg; Register.min..RegisterMax) tester.mulsd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.mulsd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.mulsd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F20F59C0F20F59C8F20F59D0F20F59D8F20F59E0F20F59E8F20F59F0F20F59F8F2440F59C0F2440F59C8F2440F59D0F2440F59D8F2440F59E0F2440F59E8F2440F59F0F2440F59F8F20F59C0F20F59C1F20F59C2F20F59C3F20F59C4F20F59C5F20F59C6F20F59C7F2410F59C0F2410F59C1F2410F59C2F2410F59C3F2410F59C4F2410F59C5F2410F59C6F2410F59C7F20F59042544332211F20F590C2544332211F20F59142544332211F20F591C2544332211F20F59242544332211F20F592C2544332211F20F59342544332211F20F593C2544332211F2440F59042544332211F2440F590C2544332211F2440F59142544332211F2440F591C2544332211F2440F59242544332211F2440F592C2544332211F2440F59342544332211F2440F593C2544332211");

	// divss
	foreach (Register reg; Register.min..RegisterMax) tester.divss(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.divss(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.divss(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F30F5EC0F30F5EC8F30F5ED0F30F5ED8F30F5EE0F30F5EE8F30F5EF0F30F5EF8F3440F5EC0F3440F5EC8F3440F5ED0F3440F5ED8F3440F5EE0F3440F5EE8F3440F5EF0F3440F5EF8F30F5EC0F30F5EC1F30F5EC2F30F5EC3F30F5EC4F30F5EC5F30F5EC6F30F5EC7F3410F5EC0F3410F5EC1F3410F5EC2F3410F5EC3F3410F5EC4F3410F5EC5F3410F5EC6F3410F5EC7F30F5E042544332211F30F5E0C2544332211F30F5E142544332211F30F5E1C2544332211F30F5E242544332211F30F5E2C2544332211F30F5E342544332211F30F5E3C2544332211F3440F5E042544332211F3440F5E0C2544332211F3440F5E142544332211F3440F5E1C2544332211F3440F5E242544332211F3440F5E2C2544332211F3440F5E342544332211F3440F5E3C2544332211");

	// divsd
	foreach (Register reg; Register.min..RegisterMax) tester.divsd(reg, Register.min);
	foreach (Register reg; Register.min..RegisterMax) tester.divsd(Register.min, reg);
	foreach (Register reg; Register.min..RegisterMax) tester.divsd(reg, memAddrDisp32(0x11223344));
	tester.assertHexAndReset("F20F5EC0F20F5EC8F20F5ED0F20F5ED8F20F5EE0F20F5EE8F20F5EF0F20F5EF8F2440F5EC0F2440F5EC8F2440F5ED0F2440F5ED8F2440F5EE0F2440F5EE8F2440F5EF0F2440F5EF8F20F5EC0F20F5EC1F20F5EC2F20F5EC3F20F5EC4F20F5EC5F20F5EC6F20F5EC7F2410F5EC0F2410F5EC1F2410F5EC2F2410F5EC3F2410F5EC4F2410F5EC5F2410F5EC6F2410F5EC7F20F5E042544332211F20F5E0C2544332211F20F5E142544332211F20F5E1C2544332211F20F5E242544332211F20F5E2C2544332211F20F5E342544332211F20F5E3C2544332211F2440F5E042544332211F2440F5E0C2544332211F2440F5E142544332211F2440F5E1C2544332211F2440F5E242544332211F2440F5E2C2544332211F2440F5E342544332211F2440F5E3C2544332211");

	auto durationTotal = currTime - startTime;
	writefln("amd64 assembler (%s/%s) successful tests in %ss",
		tester.totalTests - tester.numFailedTests,
		tester.totalTests,
		scaledNumberFmt(durationTotal));

	return tester.numFailedTests;
}
